﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;

namespace HdipCricketClub.Models
{
    [MetadataType(typeof(PlayerSeasonStatisticsMetaData))]
    public partial class PlayerSeasonStatistic
    {
        // properties

        public double BattingAverage
        {
            get
            {
                if ((batting_runs == null) || (innings == null))
                {
                    return 0;
                }

                if ((batting_runs != null) && (innings != null) && (not_out == null))
                {
                    return Math.Round((double)batting_runs / (double)innings, 2);
                }

                if ((innings - not_out) == 0)
                {
                    return 0;
                }
                else
                {
                    return Math.Round((double)batting_runs / ((double)innings - (double)not_out), 2);
                }
            }
        }

        public double BowlingAverage
        {
            get
            {
                if ((wickets != null) && (bowling_runs != null))
                {
                    return Math.Round((double)bowling_runs / (double)wickets, 2);
                }
                else
                {
                    return 0;
                }
            }
        }


        public double RunsPerOver
        {
            get
            {
                if ((bowling_runs != null) && (overs != null))
                {
                    return Math.Round((double)bowling_runs / (double)overs, 2);
                }
                else
                {
                    return 0;
                }
            }
        }

        // db context

        CricketClubEntities db = new CricketClubEntities();

        // repositories

        PlayerSeasonStatisticRepository playerSeasonStatisticsRepository = new PlayerSeasonStatisticRepository();

        // methods

        public void UpdatePlayersStatistics(List<ClubFixturePlayer> clubPlayers)
        {
            // get list of all player id's where season statistics exist

            List<int> existingPlayerStatistics = playerSeasonStatisticsRepository.GetPlayerIds();

            foreach (ClubFixturePlayer player in clubPlayers)
            {
                if (!existingPlayerStatistics.Contains(player.player_id))
                {
                    PlayerSeasonStatistic playerStatistics = new PlayerSeasonStatistic() { player_id = player.player_id };
                    
                    playerStatistics.matches = 1;

                    if (player.how_out != null)
                    {
                        if (player.how_out != 8)
                        {
                            playerStatistics.innings = 1;
                        }
                    }
                    if (player.how_out == 9)
                    {
                        playerStatistics.not_out = 1;
                    }
                    if (player.batting_runs != null)
                    {
                        playerStatistics.batting_runs = player.batting_runs;
                        playerStatistics.best_batting = player.batting_runs;
                    }
                    if (player.overs != null)
                    {
                        playerStatistics.overs = player.overs;
                    }
                    if (player.maidens != null)
                    {
                        playerStatistics.maidens = player.maidens;
                    }
                    if (player.bowling_runs != null)
                    {
                        playerStatistics.bowling_runs = player.bowling_runs;
                        playerStatistics.best_bowling_runs = player.bowling_runs;
                    }
                    if (player.wickets != null)
                    {
                        playerStatistics.wickets = player.wickets;
                        playerStatistics.best_bowling_wickets = player.wickets;
                    }

                    db.PlayerSeasonStatistics.AddObject(playerStatistics);
                    db.SaveChanges();
                }

                else if (existingPlayerStatistics.Contains(player.player_id))
                {
                    PlayerSeasonStatistic playerStatistics = db.PlayerSeasonStatistics.Where(pss => pss.player_id == player.player_id).Single();

                    playerStatistics.matches += 1;

                    if (player.how_out != null)
                    {
                        if (player.how_out != 8)
                        {
                            playerStatistics.innings += 1;
                        }
                    }
                    if (player.how_out == 9)
                    {
                        playerStatistics.not_out += 1;
                    }
                    if (player.batting_runs != null)
                    {
                        playerStatistics.batting_runs += player.batting_runs;

                        if (player.batting_runs > playerStatistics.best_batting)
                        {
                            playerStatistics.best_batting = player.batting_runs;
                        }
                    }
                    if (player.overs != null)
                    {
                        playerStatistics.overs += player.overs;
                    }
                    if (player.maidens != null)
                    {
                        playerStatistics.maidens += player.maidens;
                    }
                    if (player.bowling_runs != null)
                    {
                        playerStatistics.bowling_runs += player.bowling_runs;
                    }
                    if (player.wickets != null)
                    {
                        playerStatistics.wickets += player.wickets;

                        if (player.wickets > playerStatistics.best_bowling_wickets)
                        {
                            playerStatistics.best_bowling_wickets = player.wickets;
                            playerStatistics.best_bowling_runs = player.bowling_runs;
                        }
                        else if ((player.wickets == playerStatistics.wickets) && (player.bowling_runs < playerStatistics.best_bowling_runs))
                        {
                            playerStatistics.best_bowling_wickets = player.wickets;
                            playerStatistics.best_bowling_runs = player.bowling_runs;
                        }
                    }

                    db.ObjectStateManager.ChangeObjectState(playerStatistics, EntityState.Modified);
                    db.SaveChanges();
                }
            }
        }

        public void ResetStatistics()
        {
            List<PlayerSeasonStatistic> statistics = db.PlayerSeasonStatistics.ToList();

            foreach (PlayerSeasonStatistic playerStatistic in statistics)
            {
                db.DeleteObject(playerStatistic);
                db.SaveChanges();
            }
        }

        public void RegenerateStatistics()
        {
            // get player id's with fixtures

            List<int> players = db.ClubFixturePlayers.Select(cfp => cfp.player_id).Distinct().ToList();

            List<ClubFixturePlayer> statistics = db.ClubFixturePlayers.ToList();


            foreach (int playerId in players)
            {
                PlayerSeasonStatistic playerStatistics = new PlayerSeasonStatistic() { player_id = playerId };

                double bestBattingRuns = double.MinValue;
                double bestBowlingWickets = double.MinValue;
                double bestBowlingRuns = double.MaxValue;

                foreach (ClubFixturePlayer fixturePlayer in statistics)
                {
                    if (playerId == fixturePlayer.player_id)
                    {
                        if ((playerStatistics.matches == 0) || (playerStatistics.matches == null) && (fixturePlayer.how_out != null))
                        {
                           playerStatistics.matches = 1;
                        }
                        else if (playerStatistics.matches > 0)
                        {
                            playerStatistics.matches += 1;
                        }

                        if ((playerStatistics.not_out == 0) || (playerStatistics.not_out == null))
                        {
                            if ((fixturePlayer.how_out == 9) && (fixturePlayer.how_out != null))
                            {
                                playerStatistics.not_out = 1;
                            }
                        }
                        else if ((playerStatistics.not_out > 0) && (fixturePlayer.how_out != null))
                        {
                            if (fixturePlayer.how_out == 9)
                            {
                                playerStatistics.not_out += 1;
                            }
                        }

                        if (playerStatistics.innings == null)
                        {
                            if ((fixturePlayer.how_out != 8) && (fixturePlayer.how_out != null))
                            {
                                playerStatistics.innings = 1;
                            }
                        }
                        else if (playerStatistics.innings > 0)
                        {
                            if ((fixturePlayer.how_out != 8) && (fixturePlayer.how_out != null))
                            {
                                playerStatistics.innings += 1;
                            }
                        }

                        if (playerStatistics.batting_runs == null)
                        {
                            if (fixturePlayer.batting_runs != null)
                            {
                                playerStatistics.batting_runs = fixturePlayer.batting_runs;
                            }
                        }
                        else if (playerStatistics.batting_runs >= 0)
                        {
                            if (fixturePlayer.batting_runs != null)
                            {
                                playerStatistics.batting_runs += fixturePlayer.batting_runs;
                            }
                        }

                        if (playerStatistics.overs == null)
                        {
                            if (fixturePlayer.overs != null)
                            {
                                playerStatistics.overs = fixturePlayer.overs;
                            }
                        }
                        else
                        {
                            if(fixturePlayer.overs != null)
                            {
                            playerStatistics.overs += fixturePlayer.overs;
                            }
                        }

                        if (playerStatistics.maidens == null)
                        {
                            if (fixturePlayer.maidens != null)
                            {
                                playerStatistics.maidens = fixturePlayer.maidens;
                            }
                        }
                        else
                        {
                            if (fixturePlayer.maidens != null)
                            {
                                playerStatistics.maidens += fixturePlayer.maidens;
                            }
                        }


                        if (playerStatistics.bowling_runs == null)
                        {
                            if (fixturePlayer.bowling_runs != null)
                            {
                                playerStatistics.bowling_runs = fixturePlayer.bowling_runs;
                            }
                        }
                        else
                        {
                            if (fixturePlayer.bowling_runs != null)
                            {
                                playerStatistics.bowling_runs += fixturePlayer.bowling_runs;
                            }
                        }

                        if (playerStatistics.wickets == null)
                        {
                            if (fixturePlayer.wickets != null)
                            {
                                playerStatistics.wickets = fixturePlayer.wickets;
                            }
                        }
                        else
                        {
                            if (fixturePlayer.wickets != null)
                            {
                                playerStatistics.wickets += fixturePlayer.wickets;
                            }
                        }

                        if (fixturePlayer.batting_runs > bestBattingRuns)
                        {
                            playerStatistics.best_batting = fixturePlayer.batting_runs;
                            bestBattingRuns = (double)fixturePlayer.batting_runs;
                        }

                        if ((fixturePlayer.wickets > bestBowlingWickets) && (fixturePlayer.bowling_runs < bestBowlingRuns))
                        {
                            playerStatistics.best_bowling_wickets = fixturePlayer.wickets;
                            playerStatistics.best_bowling_runs = fixturePlayer.bowling_runs;
                            bestBowlingWickets = (double)fixturePlayer.wickets;
                            bestBowlingRuns = (double)fixturePlayer.bowling_runs;
                        }
                    }

                }
                db.PlayerSeasonStatistics.AddObject(playerStatistics);
                db.SaveChanges();
            }

        }

    }

    public class PlayerSeasonStatisticsMetaData
    {
        [Display(Name = "Matches:")]
        public object matches;

        [Display(Name = "Innings:")]
        public object innings;

        [Display(Name = "Not Out:")]
        public object not_out;

        [Display(Name = "Runs:")]
        public object batting_runs;

        [Display(Name = "Overs:")]
        public object overs;

        [Display(Name = "Maidens:")]
        public object maidens;

        [Display(Name = "Runs:")]
        public object bowling_runs;

        [Display(Name = "Wickets:")]
        public object wickets;

    }

}